﻿using System;
using SpiceNet.Simulations;

namespace SpiceNet.Integration
{
    /// <summary>
    /// A class capable of integrating noise
    /// </summary>
    public class NoiseIntegration
    {
        /// <summary>
        /// This subroutine evaluates the integral of the function
        ///     NOISE = a * (FREQUENCY) ^ EXPONENT
        ///     
        /// Given two points from the curve. If EXPONENT is relatively close to 0,
        /// the noise is simply multiplied by the change in frequency. If it isn't,
        /// a more complicted expression must be used. Note that EXPONENT = -1 gives
        /// a different equation than EXPONENT != -1.
        /// Hence, the reason for the constant N_INTUSELOG
        /// </summary>
        /// <param name="noizDens"></param>
        /// <param name="lnNdens"></param>
        /// <param name="lnNlstDens"></param>
        /// <param name="data"></param>
        public static double Integrate(double noizDens, double lnNdens, double lnNlstDens, NoiseData data)
        {
            double exponent;
            double a;

            exponent = (lnNdens - lnNlstDens) / data.delLnFreq;
            if (Math.Abs(exponent) < Noise.N_INTFTHRESH)
                return (noizDens * data.delFreq);
            else
            {
                a = Math.Exp(lnNdens - exponent * data.lnFreq);
                exponent += 1.0;
                if (Math.Abs(exponent) < Noise.N_INTUSELOG)
                    return a * (data.lnFreq - data.lnLastFreq);
                else
                    return (a * ((Math.Exp(exponent * data.lnFreq) - Math.Exp(exponent * data.lnLastFreq)) / exponent));
            }
        }
    }
}
